//
// Basic class to handle reading of static data
//
// Author: Alex V. Boreskoff
//

#include	"Data.h"

Data :: Data ( void * ptr, int len )
{
	bits   = (byte *) ptr;
	length = len;
	pos    = 0;
}

Data :: Data ( const char * fileName )
{
												// make a fix for windows to replace '/' in file path
												// to windoze style '\\' if under windoze
	char * name = _strdup ( fileName );

#ifdef	_WIN32
	char * ptr;

	while ( ( ptr = strchr ( name, '/' ) ) != NULL )
		*ptr = '\\';
#endif

	bits   = NULL;
	length = 0;
	pos    = 0;
	file   = name;

	int	fd=0;
	errno_t err = _sopen_s ( &fd,name, _O_RDONLY | _O_BINARY, _SH_DENYNO, _S_IREAD );
	free ( name );

	if (err!=0)return;

	#ifndef _WIN32
		struct	stat statBuf;
		
		fstat ( fd, &statBuf );
		
		long	len = statBuf.st_size; 
	#else	
		long	len = _filelength ( fd );
	#endif

		if ( len == -1 )
		{
			_close ( fd );

			return;
		}

		bits = (byte *) malloc ( len );

		if ( bits == NULL )
		{
			_close ( fd );

			return;
		}

		length = _read ( fd, bits, len );

		_close ( fd );
}

bool	Data :: isOk () const
{
	return bits != NULL;
}

void * Data :: getPtr ( int offs ) const
{
	if ( offs < 0 || offs >= length )
		return NULL;

	return bits + offs;
}

int	Data :: getBytes ( void * ptr, int len )
{
	if ( pos >= length )
		return -1;

	if ( pos + len > length )
		len = length - pos;

	memcpy ( ptr, bits + pos, len );

	pos += len;

	return len;
}

bool	Data ::  getString ( std::string& str, char term )
{
	if ( pos >= length )
		return false;

	str = "";

	while ( pos < length && bits [pos] != term )
		str += bits [pos++];

	if ( pos < length && bits [pos] == term )
		pos ++;
													// skin OA part of line terminator (0D,0A)
	if ( term == '\r' && pos + 1 < length && bits [pos+1] == '\n' )
		pos++;

	return true;
}
